import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.event.*;
//import javax.swing.table.*;
import javax.swing.tree.*;
import java.beans.*;  // for PropertyChangeEvent etc

public class MapFrame extends JFrame
{
   static final long serialVersionUID = 71L;
   
   private JFileChooser fc;
   private Region region; 
   private File originalDirectory;
   private Region data;
   private MapPanel mapPanel;
   private MapPanelMelbourne mapPanelMel;
   //private MapTableModel tableModel;
   private JTable table;
   private JTree tree; // 2005
   //private FerryPanel ferryPanel;
   private JPanel westPanel, colourPPanel;
   private JTabbedPane sidePane;
   private JTabbedPane mapPane;
   private JScrollPane tableScroller;  //v7.0
   private JScrollPane treeScroller;  //2005
   private JLabel status = new JLabel();
   private JRadioButton queryButton;
   private JComboBox suburbs_combobox;
  
  
   public MapFrame()
   {
      setTitle("Assignment 2 2012");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // not stage 7
      setSize(1000,580);
      colourPPanel = new JPanel();
      colourPPanel.setPreferredSize(new Dimension(25,25));
      mapPane = new JTabbedPane();
      suburbs_combobox = new JComboBox();
      suburbs_combobox.addItem("All");
      suburbs_combobox.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e) {
			mapPanel.setSelectedSuburb((String)suburbs_combobox.getSelectedItem());	
		}
    	 
     });
      
      JPanel mainPanel = new JPanel(new BorderLayout());
      JPanel north = new JPanel();
      mainPanel.add(north, "North");
      mapPanel = new MapPanel(status);
      mapPanelMel = new MapPanelMelbourne(status);
      
      mapPane.addTab("Map1", getJScrollPane());
      mapPane.addTab("Map2",getScrollPane2());
      mainPanel.add(mapPane, "Center");
      mainPanel.add(status, "South");
      westPanel = new JPanel(new BorderLayout());
      sidePane = new JTabbedPane();
      westPanel.add(sidePane, "Center");
      sidePane.addTab("Search",  searchOptionsPanel());
      sidePane.addTab("Colour", createColourDialogPanel());
  
      JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, westPanel, mainPanel);
      split.setResizeWeight(0.25);
      sidePane.setMinimumSize(new Dimension(200,400));
      sidePane.addChangeListener(new ChangeListener(){
		public void stateChanged(ChangeEvent e) {
			mapPanel.setTabMode(sidePane.getSelectedIndex());
		}  
      });
      
      getContentPane().add(split);
      JMenuBar bar = new JMenuBar(); 
      setJMenuBar(bar);
      JMenu fileMenu = new JMenu("File");
      bar.add(fileMenu);
      JMenu helpMenu = new JMenu("Help");
      bar.add(helpMenu);
      
      JMenuItem open = new JMenuItem("Open...");
      open.addActionListener(new ActionListener()
      {
          public void actionPerformed(ActionEvent e) {openAction();}
      });
      fileMenu.add(open);
      
      JMenuItem save = new JMenuItem("Save...");
      save.addActionListener(new ActionListener()
      {
          public void actionPerformed(ActionEvent e) {
              saveAction();
          }
      });
      fileMenu.add(save);
      
      fileMenu.addSeparator();
      JMenuItem exit = new JMenuItem("Exit");
      exit.addActionListener(new ActionListener()
      {
          public void actionPerformed(ActionEvent e) {
              
        	  if(data != null){
        		  
        		  // if the data has been changed 
        		  if(data.getChanged())
        		  {
        			  
        			 int confirm = showConfirmBox();
        			 if(confirm == JOptionPane.YES_OPTION){
        					 saveAction();
        					 System.exit(0);
        			 }
        			 else if(confirm == JOptionPane.NO_OPTION)
        			 {
        				 System.exit(0);
        			 }
        			 else if(confirm == JOptionPane.CANCEL_OPTION){
        				 
        				 // do nothing 
        			 }else{
        				 
        				 // do nothing 
        			 }
        			  
        		  }else{
        			 
        			  System.exit(0);
        		  }
        		  
        	  }else{
        		  System.exit(0);  
        	  }
        	 
          }
      });
      fileMenu.add(exit);
      
      JMenuItem about = new JMenuItem("About");
      about.addActionListener(new ActionListener()
      {
          public void actionPerformed(ActionEvent e) {
              JOptionPane.showMessageDialog(MapFrame.this,
              "Terry Miller , Adam Dickinson",
              "About",
              JOptionPane.PLAIN_MESSAGE);
          }
      });
      helpMenu.add(about);
   
   }   
   
   public JPanel createColourDialogPanel()
   {
	   JPanel colourPanel = new JPanel();
	   final  JColorChooser colourChooser = new JColorChooser();
	   colourChooser.setColor(Color.RED);
	   colourPPanel.setBackground(colourChooser.getColor());
	   colourPanel.add(colourChooser);
	   colourChooser.setPreviewPanel(new JPanel());
	   colourChooser.getSelectionModel().addChangeListener(new ChangeListener(){
		   public void stateChanged(ChangeEvent arg0) {
			   mapPanel.setBGColour(colourChooser.getColor());
			   colourPPanel.setBackground(colourChooser.getColor());
			   
		} });
	   return colourPanel;  
   }
   
   public int showConfirmBox()
   {
	   
	   Object[] options = {"Yes, Please",
               "No, Thanks",
               "Cancel"};
	   int n = JOptionPane.showOptionDialog(null,"You Have Unsaved Data Would You Like To Save?"+ "","Save Data",
			   JOptionPane.YES_NO_CANCEL_OPTION,
			   JOptionPane.QUESTION_MESSAGE,
			   null,options,options[2]); 
	   return n;
   }
   
   
   public JPanel searchOptionsPanel()
   {
	   JPanel holderPanel = new JPanel();
	   holderPanel.setLayout(new GridLayout(6,1));
	   JPanel selectBoxPanel = new JPanel();
	   selectBoxPanel.setLayout(new GridLayout(2,2));
	   selectBoxPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Suburbs") );
	   selectBoxPanel.add(new JLabel("Suburbs :"));
	   selectBoxPanel.add(suburbs_combobox);
	   selectBoxPanel.add(new JLabel("Current Colour : "));
	   selectBoxPanel.add(colourPPanel);
	   holderPanel.add(selectBoxPanel);
	   JPanel modePanel = new JPanel();
	   modePanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Mode") );
	   JCheckBox railButton = new JCheckBox("Rails", true);
	   modePanel.add(railButton);
	   railButton.addActionListener(new ActionListener() {
	          public void actionPerformed(ActionEvent e) {
	        	  AbstractButton abstractButton = (AbstractButton) e.getSource();
	        	  boolean selected = abstractButton.getModel().isSelected();
	        	  mapPanel.setRailCheckBox(selected);
	          }
	      } );   
	   
	      JCheckBox roadButton = new JCheckBox("Roads", true);
	      //group.add(roadButton);
	      modePanel.add(roadButton);
	      roadButton.addActionListener(new ActionListener() {
	          public void actionPerformed(ActionEvent e) {
	        	  
	        	  AbstractButton abstractButton = (AbstractButton) e.getSource();
	        	  boolean selected = abstractButton.getModel().isSelected();
	        	  mapPanel.setRoadCheckBox(selected);
	             
	          }
	      } );    
	      
	      JCheckBox suburbButton = new JCheckBox("Suburbs", true);
	      //group.add(suburbButton);
	      modePanel.add(suburbButton);
	      suburbButton.addActionListener(new ActionListener() {
	          public void actionPerformed(ActionEvent e) {
	        	  
	        	  AbstractButton abstractButton = (AbstractButton) e.getSource();
	        	  boolean selected = abstractButton.getModel().isSelected();
	        	  mapPanel.setSubCheckBox(selected);
	          }
	      } );
	      
	   holderPanel.add(modePanel);
	   
	      JPanel zoomPanel = new JPanel();
	      zoomPanel.setBorder(BorderFactory.createTitledBorder(
	      BorderFactory.createEtchedBorder(), "Zoom") );
	     
	      JButton zoomInButton = new JButton("IN");
	      zoomPanel.add(zoomInButton);
	      zoomInButton.addActionListener(new ActionListener() {
	          public void actionPerformed(ActionEvent e) {
	              mapPanel.zoomIn();
	          }
	      } );    
	      
	      JButton zoomOutButton = new JButton("OUT");
	      zoomPanel.add(zoomOutButton);
	      zoomOutButton.addActionListener(new ActionListener() {
	          public void actionPerformed(ActionEvent e) {
	              mapPanel.zoomOut();
	          }
	      } );
	      
	      JButton zoomOneButton = new JButton("1:1");
	      zoomPanel.add(zoomOneButton);
	      zoomOneButton.addActionListener(new ActionListener() {
	          public void actionPerformed(ActionEvent e) {
	              mapPanel.zoomOne();
	          }
	      } );
	     
	      JPanel blankspace = new JPanel();
	      
	      holderPanel.add(zoomPanel);
	      
	      JPanel animationPanel = new JPanel();
	      animationPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Animation") );
		  
	      JButton addCar = new JButton("Add Car");
	      zoomPanel.add(addCar);
	      addCar.addActionListener(new ActionListener() {
	          public void actionPerformed(ActionEvent e) {
	              mapPanel.addCar();
	          }
	      } );
	      
	      animationPanel.add(addCar);
	      holderPanel.add(animationPanel);
	      holderPanel.add(blankspace);
	      holderPanel.add(blankspace);
	   
	   return holderPanel;
   }
   
   public void getJCombobox()
   {
	  Set set = data.getArea().entrySet(); 
	   Iterator i = set.iterator(); 
	   while(i.hasNext()) {
			Map.Entry me = (Map.Entry)i.next();
			suburbs_combobox.addItem(me.getKey());
		} 
	}
   
   
   public JPanel returnNothing()
   {
	   return new JPanel(); 
   }
   
 
   public JScrollPane getJScrollPane()
   {
	   	JScrollPane sc = new JScrollPane(mapPanel);
	    mapPanel.setViewport(sc.getViewport());
	    sc.getViewport().addChangeListener(mapPanel);
	    return sc;
   }
   
   public JScrollPane getScrollPane2()
   {
	   
	   JScrollPane sc2 = new JScrollPane(mapPanelMel);
	   mapPanelMel.setViewport(sc2.getViewport());
	    sc2.getViewport().addChangeListener(mapPanelMel);
	    return sc2;
	   
   }

   private void openAction()
   {
       try {
    	   
          if (fc == null) 
          {
              fc =new JFileChooser("Data");
              fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
              fc.setMultiSelectionEnabled(false);
          }
          int state = fc.showOpenDialog(this);
          if (state == JFileChooser.APPROVE_OPTION)
          {
              File f = fc.getSelectedFile();
              originalDirectory = f.getParentFile();
              data = new Region();
              
              if (f.getName().toLowerCase().endsWith(".scn"))
              {
                  data.loadFromFile(f);
                  mapPanel.setData(data);
                  mapPanelMel.setData(data);
                  getJCombobox();
              }
          
          }
      }
      catch(Exception e) {
          System.err.println("error reading: " + e + "\n -- should terminate");
          e.printStackTrace();
          data = null;
      }
     // repaint();
      
   }
    
   private void saveAction()
   {
      try{
    	  
    	  if (fc == null) 
          {
              fc =new JFileChooser("Data");
              fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
              fc.setMultiSelectionEnabled(false);
          }
          int state = fc.showSaveDialog(this);
          if (state == JFileChooser.APPROVE_OPTION)
          {
              File f = fc.getSelectedFile();
              String[] filenames = new String[5];
              filenames[0] = f.getName() + "Victoria.txt";
              filenames[1] = f.getName() + "Suburbs.txt";
              filenames[2] = f.getName() + "Road.txt";
              filenames[3] = f.getName() + "Rail.txt";
              
              data.getManager().createSCNFile(f.getName(),filenames, "|");
              data.getManager().saveState(data.getState(), filenames[0], "|");
              data.getManager().saveSuburbs(data.getArea(), filenames[1], "|");
              data.getManager().saveRoads(data.getRoad(),filenames[2] , "|");
              data.getManager().saveRails(data.getRail(), filenames[3], "|");
              
              data.setChanged(false);
          }
      }
      catch(Exception e) {
          System.err.println("error writing: " + e + "\n -- should terminate");
      }
	   
	   
   }
   
 
   public static void main(String[] args)
   {
      JFrame frame = new MapFrame();
      frame.setVisible(true);  
   }
}

